home *** CD-ROM | disk | FTP | other *** search
- From: Andreas Schwab <schwab@lamothe.informatik.uni-dortmund.de>
- Date: Tue, 23 Nov 93 11:09:20 +0100
- Message-Id: <9311231009.AA01151@lamothe.informatik.uni-dortmund.de>
- To: mint@atari.archive.umich.edu
- Subject: MiNT 1.09 extension: /dev/fd/*
-
- This patch implements the /dev/fd directory, denoting the open file
- descriptors of the current process. This is a generalisation of
- /dev/std{in,out,err}.
-
- I have implemented this for Bash-1.13, which uses it for process
- substitution; unfortunately this doesn't work because of the blocking
- fork() :-(. Anyway, i think this is a nice thing.
-
- --- orig/biosfs.c Tue Aug 17 21:23:18 1993
- +++ biosfs.c Sat Nov 20 19:50:40 1993
- @@ -136,6 +136,7 @@
- {"stdin", &fakedev, 0, 0, 0, 0}, /* handle 0 (stdin) */
- {"stdout", &fakedev, 1, 0, 0, 0}, /* handle 1 (stdout) */
- {"stderr", &fakedev, 2, 0, 0, 0}, /* handle 2 (stderr) */
- + {"fd", &fakedev, S_IFDIR, 0, 0, 0}, /* file descriptor directory */
-
- /* other miscellaneous devices */
- {"mouse", &mouse_device, 0, 0, 0, 0},
- @@ -157,6 +158,11 @@
- {"", 0, 0, 0, 0, 0}
- };
-
- +/* Does the fcookie fc refer to the \dev\fd directory? */
- +#define IS_FD_DIR(fc) ((fc)->aux == S_IFDIR)
- +/* Does the fcookie fc refer to a file in the \dev\fd directory? */
- +#define IS_FD_ENTRY(fc) ((fc)->index > 0 && (fc)->index <= MAX_OPEN-MIN_HANDLE)
- +
- struct bios_file *broot, *bdevlast;
-
- /* a file pointer for BIOS device 1, provided only for insurance
- @@ -234,9 +240,41 @@
- struct bios_file *b;
-
- if (dir->index != 0) {
- + /* Check for \dev\fd directory */
- + if (!IS_FD_DIR (dir))
- + {
- DEBUG(("bios_lookup: bad directory"));
- return EPTHNF;
- + }
- + if (!*name || (name[0] == '.' && name[1] == 0))
- + {
- + *fc = *dir;
- + return 0;
- + }
- + if (!strcmp (name, ".."))
- + {
- + /* Root directory */
- + fc->fs = &bios_filesys;
- + fc->dev = dir->dev;
- + fc->index = 0L;
- + return 0;
- + }
- + if (isdigit (*name) || *name == '-')
- + {
- + int fd = (int) atol (name);
- + if (fd >= MIN_HANDLE && fd < MAX_OPEN)
- + {
- + fc->fs = &bios_filesys;
- + fc->dev = dir->dev;
- + fc->aux = fd;
- + fc->index = fd - MIN_HANDLE + 1;
- + return 0;
- + }
- + }
- + DEBUG (("bios_lookup: name(%s) not found", name));
- + return EFILNF;
- }
- +
- /* special case: an empty name in a directory means that directory */
- /* so does "." */
- if (!*name || (name[0] == '.' && name[1] == 0)) {
- @@ -270,6 +308,7 @@
- {
- FILEPTR *f;
- struct bios_file *b = (struct bios_file *)fc->index;
- + long r;
-
- xattr->index = fc->index;
- xattr->dev = fc->dev;
- @@ -279,18 +318,42 @@
- xattr->blksize = 1;
- xattr->mtime = xattr->atime = xattr->ctime = timestamp;
- xattr->mdate = xattr->adate = xattr->cdate = datestamp;
- - if (fc->index == 0) { /* root directory? */
- + if (fc->index == 0 || IS_FD_DIR (fc)) { /* root or fd directory? */
- xattr->mode = S_IFDIR | DEFAULT_DIRMODE;
- xattr->attr = FA_DIR;
- + }
- + else if (IS_FD_ENTRY (fc)) {
- + /* u:\dev\fd\... */
- + f = curproc->handle[(int) fc->aux];
- + if (f)
- + {
- + r = (*f->fc.fs->getxattr) (&f->fc, xattr);
- + if (r < 0)
- + return r;
- +#if 0
- + /* Not sure if needed. Try without it for now */
- + xattr->index = fc->index;
- + xattr->dev = fc->dev;
- +#endif
- + }
- + else
- + {
- + xattr->mode = S_IFCHR | DEFAULT_MODE;
- + xattr->attr = 0;
- + }
- } else if (b->device == 0) { /* symbolic link? */
- xattr->mode = S_IFLNK | DEFAULT_DIRMODE;
- } else if (b->device == &fakedev &&
- (f = curproc->handle[b->private]) != 0)
- {
- /* u:\dev\stdin, u:\dev\stdout, etc. */
- - (*f->fc.fs->getxattr) (&f->fc, xattr);
- + r = (*f->fc.fs->getxattr) (&f->fc, xattr);
- + if (r < 0)
- + return r;
- +#if 0
- xattr->index = fc->index;
- xattr->dev = fc->dev;
- +#endif
- } else {
- xattr->mode = S_IFCHR | DEFAULT_MODE;
- xattr->attr = 0;
- @@ -357,7 +420,10 @@
- {
- struct bios_file *b, **lastb;
-
- - UNUSED(dir);
- + /* Don't allow removal in the fd directory */
- + if (IS_FD_DIR (dir))
- + return EACCDN;
- +
- lastb = &broot;
- for (b = broot; b; b = *(lastb = &b->next)) {
- if (!stricmp(b->name, name)) break;
- @@ -382,12 +448,22 @@
- fcookie *root, *dir; char *pathname;
- int size;
- {
- - char *foo = ((struct bios_file *)dir->index)->name;
- + char *foo;
-
- - UNUSED(root);
- - if (dir->index == 0 && size > 0)
- - *pathname = 0;
- - else if (strlen(foo) < size)
- + if (size == 0)
- + return ERANGE;
- + if (root->index == dir->index)
- + {
- + *pathname = 0;
- + return 0;
- + }
- + /* DIR must point to the fd directory */
- + if (!IS_FD_DIR (dir))
- + return EINTRN;
- + *pathname++ = '\\';
- + size--;
- + foo = ((struct bios_file *)dir->index)->name;
- + if (strlen(foo) < size)
- strcpy(pathname, foo);
- else
- return ERANGE;
- @@ -401,18 +477,22 @@
- fcookie *newdir;
- const char *newname;
- {
- - struct bios_file *b;
- -
- - UNUSED(olddir); UNUSED(newdir);
- + struct bios_file *b, *be = 0;
-
- -/* BUG: we should check to see if "newname" already exists */
- + if (IS_FD_DIR (olddir) || IS_FD_DIR (newdir))
- + return EACCDN;
-
- for (b = broot; b; b = b->next) {
- - if (!stricmp(b->name, oldname)) {
- - strncpy(b->name, newname, BNAME_MAX);
- - return 0;
- - }
- - }
- + if (!stricmp(b->name, oldname))
- + be = b;
- + else if (!stricmp (b->name, newname))
- + return EACCDN;
- + }
- + if (be)
- + {
- + strncpy(be->name, newname, BNAME_MAX);
- + return 0;
- + }
- return EFILNF;
- }
-
- @@ -423,7 +503,7 @@
- {
- UNUSED(flags);
-
- - if (dirh->fc.index != 0) {
- + if (dirh->fc.index != 0 && !IS_FD_DIR (&dirh->fc)) {
- DEBUG(("bios_opendir: bad directory"));
- return EPTHNF;
- }
- @@ -440,6 +520,31 @@
- struct bios_file *b;
- int giveindex = dirh->flags == 0;
- int i;
- + char buf[5];
- +
- + if (IS_FD_DIR (&dirh->fc))
- + {
- + i = dirh->index++;
- + if (i + MIN_HANDLE >= MAX_OPEN)
- + return ENMFIL;
- + fc->fs = &bios_filesys;
- + fc->index = i + 1;
- + fc->aux = i + MIN_HANDLE;
- + fc->dev = dirh->fc.dev;
- + if (giveindex)
- + {
- + namelen -= (int) sizeof (long);
- + if (namelen <= 0)
- + return ERANGE;
- + *(long *) name = (long) i + 1;
- + name += sizeof (long);
- + }
- + ksprintf (buf, "%d", i + MIN_HANDLE);
- + strncpy (name, buf, namelen-1);
- + if (strlen (buf) >= namelen)
- + return ENAMETOOLONG;
- + return 0;
- + }
-
- b = broot;
- i = dirh->index++;
- @@ -551,7 +656,9 @@
- {
- struct bios_file *b;
-
- - UNUSED(dir);
- + if (IS_FD_DIR (dir))
- + return EINVFN;
- +
- if ((unsigned)cmd == DEV_INSTALL) {
- struct dev_descr *d = (struct dev_descr *)arg;
-
- @@ -609,6 +716,9 @@
- long r;
- fcookie fc;
-
- + if (IS_FD_DIR (dir))
- + return EACCDN;
- +
- r = bios_lookup(dir, name, &fc);
- if (r == 0) return EACCDN; /* file already exists */
- if (r != EFILNF) return r; /* some other error */
- @@ -640,6 +750,8 @@
- {
- struct bios_file *b = (struct bios_file *)fc->index;
-
- + if (IS_FD_DIR (fc) || IS_FD_ENTRY (fc))
- + return EINVFN;
- if (!b) return EINVFN;
- if (b->device) return EINVFN;
-
- @@ -758,6 +870,13 @@
- {
- struct bios_file *b;
-
- + /* Check for \dev\fd\... */
- + if (IS_FD_ENTRY (fc))
- + {
- + *devsp = (int) fc->aux;
- + return &fakedev;
- + }
- +
- b = (struct bios_file *)fc->index;
-
- if (b->device && b->device != &fakedev)
-